"""
pd.to_numeric


作用：将参数转换为数字类型。
默认返回dtype为float64或int64， 具体取决于提供的数据。使用downcast参数获取其他dtype。

参数描述
    args 接受 scalar, list, tuple, 1-d array, or Series类型
    errors 有3种类型 {‘ignore’, ‘raise’, ‘coerce’}, 默认为‘raise’
    downcast {‘integer’, ‘signed’, ‘unsigned’, ‘float’} , default None,默认返回float64或int64
    注意downcast的意思是向下转换


errors中参数的解释
    'raise’参数：无效的解析将引发异常

    'corece’参数：将无效解析设置为NaN

    ‘ignore’参数：**无效的解析将返回输入


downcast中参数的意义
    默认的None就是不进行处理

    ‘integer’和’signed’：最小的有符号整数dtype（最小值np.int8）

    ‘unsigned’：最小的unsigned int dtype（np.uint8）

    ‘float’：最小的float dtype（np.float32）


返回值：如果解析成功，则为数字。其中返回类型取决于输入。如果为Series，则为Series，否则为ndarray。
"""
import pandas as pd

df = pd.DataFrame(
    data={
        "a": [1, 2, 3],
        "b": [1, pd.NA, 3],
        "c": [1, 2, 3],
    }
)
print(df)

df.loc['Row_sum'] = df.apply(lambda x: pd.to_numeric(x, errors='coerce').sum())  # 所有列纵向求和，并添加到结尾
print(df)

df['Col_sum'] = df.apply(lambda x: pd.to_numeric(x, errors='coerce').sum(), axis=1)  # 所有列横向求和
# df['Col_sum'] = df.loc[:, ['a', 'b']].apply(lambda x: pd.to_numeric(x, errors='coerce').sum(), axis=1)  # 指定列横向求和
print(df)

# pd.to_numeric
s = pd.Series(['apple', '1.0', '2', '2019-01-02', 1, False, None, pd.Timestamp('2018-01-05')])

# to_numeric 是在 object, 时间格式中间做转换, 然后再使用 astype 做 numeric 类型的内部转换
pd.to_numeric(s, errors='raise')  # 遇到非数字字符串类型报错, bool 类型报错, 时间类型转换为 int
pd.to_numeric(s, errors='ignore')  # 只对数字字符串转换, 其他类型一律不转换, 包含时间类型
pd.to_numeric(s, errors='coerce')  # 将时间字符串和 bool 类型转换为数字, 其他均转换为 NaN

# downcast 可以进一步转化为 int 或者 float
pd.to_numeric(s)  # 默认 float64 类型
pd.to_numeric(s, downcast='signed')  # 转换为整型

# astype 中的 error 没有`coerce`选项, 所以只适合`numeric`内部类型的转换, 比如将 int32 转换为 int64, int32 转换为 float32
# 而不适合在 object, 时间格式之间做转换,
s.astype('int32', errors='raise')
s.astype('int32', errors='ignore')  # 对object无效,astype只能对numeric类型生效
